home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
glass
/
glass.lha
/
GLASS
/
contsens
/
size.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-31
|
31KB
|
1,260 lines
/* Copyright (C) 1990 Riet Oolman
This file is part of GLASS.
GLASS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GLASS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GLASS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* file: size.c
author: H. Oolman
last modified: 13-7-1990
purpose: procedures for checking if connections have the
required size, and replacing ':' and indexing by
something equivalent.
Assuming that the input was type-correct Glass, and
passed through the macro-expander
modifications: p2c translated, tmc access procs
*/
#include "handleds.h"
#include "check.ds.h"
#include "check.var.h"
#include "check.afuncs.h"
#include "errorenv.h"
#include "unification.h"
#include "size.h"
Local typcrec *typeval PP((int appnon, val vl, envrec *btns,
long splitlevel));
Local Void unparsfc(f, fc)
FILE *f;
formcon fc;
{
/* unparses formconptr's */
switch (fc->tag) {
case TAGFCComp:
putc('(', f);
unparsfc(f, fc->FCComp.fcfirst);
fprintf(f, "): ");
unparsfc(f, fc->FCComp.fcrest);
break;
case TAGFCList:
putc('[', f);
fc = fc->FCList.l;
while (fc != NULL) {
unparsfc(f, fc);
fc = fc->next;
if (fc != NULL)
fprintf(f, ", ");
}
putc(']', f);
break;
case TAGFCSym:
Writesymbol(f, fc->FCSym.sym);
break;
}
} /* unparsfc */
Local Void unparsval(f, vl)
FILE *f;
val vl;
{
/* unparses (most) val's */
parval atv;
switch (vl->tag) {
case TAGVSym:
Writesymbol(f, vl->VSym.sym);
break;
case TAGVAtom:
Writesymbol(f, vl->VAtom.atnm);
atv = vl->VAtom.atvpar;
while (atv != NULL) {
putc(' ', f);
switch (atv->tag) {
case TAGParInt:
fprint_inum(f, atv->ParInt.i);
break;
case TAGParFlo:
fprint_fnum(f, atv->ParFlo.f);
break;
case TAGParStr:
fprint_string(f, atv->ParStr.s);
break;
case TAGParBool:
if (atv->ParBool.b)
fprintf(f, "TRUE");
else
fprintf(f, "FALSE");
break;
}
atv = atv->next;
}
fprintf(f, " (");
unparsval(f, vl->VAtom.atcpar);
putc(')', f);
break;
case TAGVLambda:
if (vl->VLambda.lval == NULL)
unparsfc(f, vl->VLambda.lpar);
else {
putc('%', f);
unparsfc(f, vl->VLambda.lpar);
putc('.', f);
unparsval(f, vl->VLambda.lval);
}
break;
case TAGVSigma:
putc('$', f);
unparsfc(f, vl->VSigma.spar);
putc('.', f);
unparsval(f, vl->VSigma.sval);
break;
case TAGVApply:
unparsval(f, vl->VApply.aval);
fprintf(f, " (");
unparsval(f, vl->VApply.apar);
putc(')', f);
break;
case TAGVWhere:
unparsval(f, vl->VWhere.wval);
if (vl->VWhere.wdefs != NULL)
fprintf(f, " Where .... Endwhere");
break;
case TAGVList:
putc('[', f);
vl = vl->VList.l;
while (vl != NULL) {
unparsval(f, vl);
vl = vl->next;
if (vl != NULL)
fprintf(f, ", ");
}
putc(']', f);
break;
case TAGVAppset:
putc('{', f);
vl = vl->VAppset.aps;
while (vl != NULL) {
unparsval(f, vl);
vl = vl->next;
if (vl != NULL)
fprintf(f, ", ");
}
putc('}', f);
break;
case TAGVSyn:
fprintf(f, "*[");
vl = vl->VSyn.synlist;
while (vl != NULL) {
unparsval(f, vl);
vl = vl->next;
if (vl != NULL)
fprintf(f, ", ");
}
putc(']', f);
break;
case TAGVInd:
unparsval(f, vl->VInd.vexp);
putc(' ', f);
fprint_inum(f, vl->VInd.vind);
break;
case TAGVSlice:
unparsval(f, vl->VSlice.vexps);
fprintf(f, " @(");
fprint_inum(f, vl->VSlice.vind1);
fprintf(f, ")...(");
fprint_inum(f, vl->VSlice.vind2);
putc(')', f);
break;
case TAGVComp:
putc('(', f);
unparsval(f, vl->VComp.vfirst);
fprintf(f, "): ");
unparsval(f, vl->VComp.vrest);
break;
}
} /* unparsval */
Local dirgraphrec *extractdirs(t)
typ t;
{ /* extract the directions in a systemtype. Easy for comparing */
switch (t->tag) {
case TAGTypUni:
return BuildCd(BuildOd(BuildIN()),
BuildCd(BuildOd(BuildOUT()),
BuildOd(BuildNON())));
break;
case TAGTypNon:
return extractdirs(t->TypNon.nontyp);
break;
case TAGTypProd:
if (t->TypProd.ptypes == NULL)
return BuildOd(BuildNON());
else {
return BuildCd(extractdirs(t->TypProd.ptypes),
extractdirs(new_TypProd(t->TypProd.ptypes->next)));
}
break;
case TAGTypBase:
return BuildOd(BuildNON());
break;
case TAGTypIn:
return BuildOd(BuildIN());
break;
case TAGTypOut:
return BuildOd(BuildOUT());
break;
case TAGTypSym:
return BuildOd(BuildNON());
break;
}
}
Local typcrec *convtype(partyps, glty, btns, mustsy)
partyp partyps;
typ glty;
envrec *btns;
boolean mustsy;
{ /* partyps: parametertypes before glty
glty: glass type to be converted to tc form
btns: TN names plus types in glty
mustsy: glty must be a system type */
symbol n;
typcrec *t1, *t2, *tc;
if (mustsy && glty->tag != TAGTypUni && glty->tag != TAGTypNon
&& glty->tag != TAGTypSym)
error(23L, NULL, NULL, NULL, NULL, false);
if (partyps != NULL) {
t2 = convtype(partyps->next, glty, btns, false);
switch (partyps->tag) {
case TAGPTInt:
t1 = BuildINT();
break;
case TAGPTFlo:
t1 = BuildFLOAT();
break;
case TAGPTStr:
t1 = BuildSTRING();
break;
case TAGPTBool:
t1 = BuildBOOL();
break;
}
return (BuildSINGLEARROW(t1, t2));
}
switch (glty->tag) {
case TAGTypBase:
n = glty->TypBase.basenm;
tc = lookup(btns, &n);
if (tc == NULL) {
error(1L, NULL, NULL, n, NULL, false);
/* should not occur */
return BuildUNKNOWN(newname(), false, false);
} else
return tc;
break;
case TAGTypIn:
return convtype(NULL, glty->TypIn.ityp, btns, false);
break;
case TAGTypOut:
return convtype(NULL, glty->TypOut.otyp, btns, false);
break;
case TAGTypUni:
return BuildSYSTY(extractdirs(glty),
BuildCT(convtype(NULL, glty->TypUni.uityp, btns, false),
BuildCT(convtype(NULL, glty->TypUni.uotyp, btns,false),
BuildEMPTYT())));
break;
case TAGTypNon:
return BuildSYSTY(extractdirs(glty),
convtype(NULL, glty->TypNon.nontyp, btns, false));
break;
case TAGTypProd:
if (glty->TypProd.ptypes == NULL)
return BuildEMPTYT();
else {
return
BuildCT(convtype(NULL,glty->TypProd.ptypes,btns,false),
convtype(NULL,new_TypProd(glty->TypProd.ptypes->next),
btns, false));
}
break;
case TAGTypSym:
n = glty->TypSym.sym;
tc = lookup(btns, &n);
if (tc == NULL) {
error(1L, NULL, NULL, n, NULL, false);
/* should not occur */
return BuildUNKNOWN(newname(), false, false);
} else
return tc;
break;
}
} /* convtype */
Local envrec *extendbtns(elts, btns)
def elts;
envrec *btns;
{
/* btns: environment of TYPE names + tc-form of defining types;
elts: list of defs, the TYPEs from which are to extend btns
for forming the result;
in the tc types in this btns env. names for TY have been
replaced by redirections to the defining types */
def hel;
symbol n;
typcrec *ut, *t;
orig oo;
hel = elts;
while (hel != NULL) {
if (hel->tag == TAGDefBasetype)
update(&btns, hel->DefBasetype.basename,
BuildBASETY(hel->DefBasetype.basename, newname(),
hel->DefBasetype.baseorig));
else {
if (hel->tag == TAGDefTyp)
update(&btns, hel->DefTyp.typnm,
BuildUNKNOWN(newname(), false, false));
}
/* fist put all typenamings in btns with unknown type */
hel = hel->next;
}
hel = elts;
while (hel != NULL) {
if (hel->tag == TAGDefTyp) {
n = hel->DefTyp.typnm;
addcopy(n, &nestednames);
oo = nestednorig;
nestednorig = hel->DefTyp.typorig;
t = convtype(NULL, hel->DefTyp.typas, btns, true);
nestednames = nestednames->next;
nestednorig = oo;
ut = lookup(btns, &n);
/* replace the unknown type by indir. to the found one */
becomes(ut, t);
}
hel = hel->next;
}
return btns;
} /* extendbtns */
Local Void extendenvloc(elts, btns)
def elts;
envrec *btns;
{
/* put types of ATOMs, DEFs in curenv, given btns for names in
the declared types */
def hel;
orig oo;
hel = elts;
while (hel != NULL) {
if (hel->tag == TAGDefVal) {
addcopy(hel->DefVal.valnm, &nestednames);
oo = nestednorig;
nestednorig = hel->DefVal.valorig;
update(&curenv, hel->DefVal.valnm,
convtype(NULL, hel->DefVal.valtyp, btns, true));
nestednames = nestednames->next;
nestednorig = oo;
} else {
if (hel->tag == TAGDefAtom) {
addcopy(hel->DefAtom.atnm, &nestednames);
oo = nestednorig;
nestednorig = hel->DefAtom.atorig;
update(&curenv, hel->DefAtom.atnm,
convtype(hel->DefAtom.atptyp, hel->DefAtom.atctyp,
btns, true));
nestednames = nestednames->next;
nestednorig = oo;
}
}
hel = hel->next;
}
} /* extendenvloc */
Local typcrec *typefc(fc)
formcon fc;
{
/* gives type of fc; adds types for names to curenv
type for name not overwritten */
typcrec *t1;
symbol hn;
switch (fc->tag) {
case TAGFCComp:
t1 = typefc(fc->FCComp.fcrest);
fc->FCComp.typfc = t1;
return BuildCT(typefc(fc->FCComp.fcfirst), t1);
break;
case TAGFCList:
if (fc->FCList.l == NULL)
return BuildEMPTYT();
else {
return BuildCT(typefc(fc->FCList.l),
typefc(new_FCList(fc->FCList.l->next)));
}
break;
case TAGFCSym:
hn = fc->FCSym.sym;
t1 = lookup(curenv, &hn);
if (t1 == NULL) {
t1 = BuildUNKNOWN(newname(), false, true);
update(&curenv, hn, t1);
}
return t1;
break;
}
} /* typefc */
#define forcefctoval(f) new_VLambda(f, NULL)
/* forcefctoval(f) new_VLambda(f, NULL):
forces an formcon to look like a val by putting a
TAGVLambda with empty lval field around it */
#define NoOrig new_orig("nofile", 0L)
/* NoOrig new_orig("nofile", 0L): a value for orig if there is none */
Local boolean tuptyp(ty, size)
typcrec *ty;
long *size;
{
/* checks if ty does not end in something else than empty, and
if not, delivers the number of component types */
while (ty->kind == kindINDIR) ty = ty->INDIR.tcind;
if (ty->kind == kindCT) {
if (!tuptyp(ty->CT.tcrest, size))
return false;
(*size)++;
return true;
} else if (ty->kind == kindEMPTYT) {
*size = 0;
return true;
} else return false;
} /* tuptyp */
Local val VSymlist(size)
long size;
{
/* delivers '[unu_'_extsupply, ... , unu_'_extsupply+size-1
extsupply is increased by size */
symbol unu;
val hv, hvl, list;
long i;
hvl = NULL;
list = NULL;
for (i = 0; i < size; i++) {
unu = Buildsymbol("unu_'", 5L);
addext(unu, extsupply);
extsupply++;
hv = new_VSym(NoOrig, unu);
if (hvl == NULL)
list = hv;
else
hvl->next = hv;
hvl = hv;
}
return new_VList(list);
} /* VSymlist */
Local Void FCSymVSymlist(size, flist, vlist)
long size;
formcon *flist;
val *vlist;
{
/* delivers '[unu_'_extsupply, ... , unu_'_extsupply+size-1 as
valptr and formconptr; extsupply is increased by size */
symbol unu;
formcon hf, hfl;
val hv, hvl;
long i;
hvl = NULL;
*flist = NULL;
*vlist = NULL;
for (i = 0; i < size; i++) {
unu = Buildsymbol( "unu_'", 5L);
addext(unu, extsupply);
extsupply++;
hf = new_FCSym(unu);
hv = new_VSym(NoOrig, unu);
if (hvl == NULL) {
*flist = hf;
*vlist = hv;
} else {
hfl->next = hf;
hvl->next = hv;
}
hfl = hf;
hvl = hv;
}
*flist = new_FCList(*flist);
*vlist = new_VList(*vlist);
} /* FCSymVSymlist */
Local Void rcifc(fc, newwheres)
formcon fc;
def *newwheres;
{ /* does the same as replconsind(fc,true,newwheres) */
def nw1, nw2;
formcon ff, fr;
val vr;
long k;
switch (fc->tag) {
case TAGFCComp:
if (tuptyp(fc->FCComp.typfc, &k)) {
rcifc(fc->FCComp.fcfirst, &nw1);
rcifc(fc->FCComp.fcrest, &nw2);
*newwheres=app_def_list(nw1, nw2);
if (fc->FCComp.fcrest->tag == TAGFCList)
fr = fc->FCComp.fcrest;
else {
if (fc->FCComp.fcrest->tag == TAGFCSym) {
FCSymVSymlist(k, &fr, &vr);
*newwheres=
app_def_list
(new_DefCon
(NoOrig,
new_VSym(NoOrig, fc->FCComp.fcrest->FCSym.sym),
vr),
*newwheres);
}
}
ff = fc->FCComp.fcfirst;
fc->tag = TAGFCList;
fc->FCList.l = ff;
fc->FCList.l->next = fr->FCList.l;
} else {
error(27L, NULL, NULL, NULL, forcefctoval(fc), false);
*newwheres = NULL;
}
break;
case TAGFCSym:
*newwheres = NULL;
break;
case TAGFCList:
nw2 = NULL;
ff = fc->FCList.l;
while (ff != NULL) {
rcifc(ff, &nw1);
nw2=app_def_list(nw2, nw1);
ff = ff->next;
}
*newwheres = nw2;
break;
}
} /* rcifc */
Local Void replconsind(vl, isw, newwheres)
val vl;
boolean isw;
def *newwheres;
{
/* replace
'x:y' by [x,y0,...,yn-1]
'y i' (indexing) by yi WHERE [y0,...,yn-1] = y ENDWHERE
'y@i...j' by [yi,...,yj]
if y has n components (n deduced from y's type)
An error occurs if the exact size of y is not known
isw: vl is used as the lhs in a where equation */
def nw1, nw2, d;
val vf, vr, hvl, hvn;
long i, k, ind1, ind2;
switch (vl->tag) {
case TAGVComp:
if (tuptyp(vl->VComp.typvc, &k)) {
replconsind(vl->VComp.vfirst, isw, &nw1);
replconsind(vl->VComp.vrest, isw, &nw2);
*newwheres=app_def_list(nw1, nw2);
if (vl->VComp.vrest->tag == TAGVList)
vr = vl->VComp.vrest;
else {
vr = VSymlist(k);
if (isw)
d=new_DefCon(NoOrig, vl->VComp.vrest, vr);
else
d=new_DefCon(NoOrig, vr, vl->VComp.vrest);
*newwheres=app_def_list(d, *newwheres);
}
vf = vl->VComp.vfirst;
vl->tag = TAGVList;
vl->VList.l = vf;
vl->VList.l->next = vr->VList.l;
} else {
error(27L, NULL, NULL, NULL, vl, false);
*newwheres = NULL;
}
break;
case TAGVInd:
if (tuptyp(vl->VInd.typvi, &k)) {
replconsind(vl->VInd.vexp, false, newwheres);
if (vl->VInd.vexp->tag == TAGVList)
vr = vl->VInd.vexp;
else {
vr = VSymlist(k);
if (isw)
d=new_DefCon(NoOrig, vl->VInd.vexp, vr);
else
d=new_DefCon(NoOrig, vr, vl->VInd.vexp);
*newwheres=app_def_list(d, *newwheres);
}
vr = vr->VList.l;
ind1 = vl->VInd.vind;
for (i = 0; i < ind1; i++)
vr = vr->next;
vf = vl->next;
*vl = *vr;
vl->next = vf;
} else {
error(27L, NULL, NULL, NULL, vl, false);
*newwheres = NULL;
}
break;
case TAGVSlice:
ind1 = vl->VSlice.vind1;
ind2 = vl->VSlice.vind2;
if (ind2 < ind1) {
vl->tag = TAGVList;
vl->VList.l = NULL;
*newwheres = NULL;
} else {
if (tuptyp(vl->VSlice.typvs, &k)) {
replconsind(vl->VSlice.vexps, false, newwheres);
if (vl->VSlice.vexps->tag == TAGVList)
vr = vl->VSlice.vexps;
else {
vr = VSymlist(k);
if (isw)
d=new_DefCon(NoOrig, vl->VSlice.vexps, vr);
else
d=new_DefCon(NoOrig, vr, vl->VSlice.vexps);
*newwheres=app_def_list(d, *newwheres);
}
vr = vr->VList.l;
for (i = 0; i < ind1; i++)
vr = vr->next;
k = ind2 - ind1;
hvl = (val )malloc(sizeof(*hvl));
*hvl = *vr;
vf = hvl;
for (i = 0; i < k; i++) {
vr = vr->next;
hvn = (val )malloc(sizeof(*hvn));
*hvn = *vr;
hvl->next = hvn;
hvl = hvn;
}
hvl->next = NULL;
vl->tag = TAGVList;
vl->VList.l = vf;
} else {
error(27L, NULL, NULL, NULL, vl, false);
*newwheres = NULL;
}
}
break;
case TAGVSym:
*newwheres = NULL;
break;
case TAGVLambda:
rcifc(vl->VLambda.lpar, &nw1);
replconsind(vl->VLambda.lval, false, &nw2);
nw2 = app_def_list(nw1,nw2);
if (nw2!=NULL)
{ if (vl->VLambda.lval->tag == TAGVWhere) {
vl->VLambda.lval->VWhere.wdefs =
app_def_list(nw2, vl->VLambda.lval->VWhere.wdefs);
} else {
vl->VLambda.lval = new_VWhere(nw2, vl->VLambda.lval);
};
}
*newwheres = NULL;
break;
case TAGVSigma:
rcifc(vl->VSigma.spar, &nw1);
replconsind(vl->VSigma.sval, false, &nw2);
nw2=app_def_list(nw1,nw2);
if (nw2!=NULL)
{ if (vl->VSigma.sval->tag == TAGVWhere) {
vl->VSigma.sval->VWhere.wdefs =
app_def_list(nw2, vl->VSigma.sval->VWhere.wdefs);
} else {
vl->VSigma.sval = new_VWhere(nw2,vl->VSigma.sval);
};
}
*newwheres = NULL;
break;
case TAGVApply:
replconsind(vl->VApply.aval, false, &nw1);
replconsind(vl->VApply.apar, false, &nw2);
*newwheres=app_def_list(nw1, nw2);
break;
case TAGVWhere:
replconsind(vl->VWhere.wval, false, &nw2);
d = vl->VWhere.wdefs;
while (d != NULL) {
if (d->tag == TAGDefCon) {
replconsind(d->DefCon.defcon, true, &nw1);
nw2=app_def_list(nw2, nw1);
replconsind(d->DefCon.conas, false, &nw1);
nw2=app_def_list(nw2, nw1);
} else {
if (d->tag == TAGDefVal)
replconsind(d->DefVal.valas, false, &nw2);
}
d = d->next;
}
if (vl->VWhere.wdefs != NULL) {
vl->VWhere.wdefs = app_def_list(nw2, vl->VWhere.wdefs);
*newwheres = NULL;
} else
*newwheres = nw2;
break;
case TAGVList:
nw2 = NULL;
hvl = vl->VList.l;
while (hvl != NULL) {
replconsind(hvl, isw, &nw1);
nw2=app_def_list(nw2, nw1);
hvl = hvl->next;
}
*newwheres = nw2;
break;
case TAGVAppset:
nw2 = NULL;
hvl = vl->VAppset.aps;
while (hvl != NULL) {
replconsind(hvl, false, &nw1);
nw2=app_def_list(nw2, nw1);
hvl = hvl->next;
}
*newwheres = nw2;
break;
case TAGVSyn:
nw2 = NULL;
hvl = vl->VSyn.synlist;
while (hvl != NULL) {
replconsind(hvl, false, &nw1);
nw2=app_def_list(nw2, nw1);
hvl = hvl->next;
}
*newwheres = nw2;
break;
case TAGVAtom:
replconsind(vl->VAtom.atcpar, false, newwheres);
break;
}
} /* replconsind */
Local Void checkdm(dm, ty, btns)
val dm;
typcrec *ty;
envrec *btns;
{
/* check if def dm has required size in type ty
ty: type of dm
btns: TNs holding on this level */
mark_(&curenv);
while (ty->kind == kindINDIR) ty = ty->INDIR.tcind;
compat(typeval(false, dm, btns, 0L), ty, dm);
release_(&curenv, false); /* remove conn. names */
} /* checkdm */
Local Void checkdms(elts, btns)
def elts;
envrec *btns;
{
/* check each DEF in the elts-list for size corr., given
btns for names in the declared types */
def hel;
symbol n;
orig oo;
hel = elts;
while (hel != NULL) {
if (hel->tag == TAGDefVal) {
n = hel->DefVal.valnm;
addcopy(n, &nestednames);
oo = nestednorig;
nestednorig = hel->DefVal.valorig;
checkdm(hel->DefVal.valas, lookup(curenv, &n), btns);
nestednames = nestednames->next;
nestednorig = oo;
}
hel = hel->next;
}
} /* checkdms */
Local typcrec *typename(n)
symbol *n;
{
/* find type of n in curenv; if not there, give it any conn.
type */
typcrec *t;
t = lookup(curenv, n);
if (t == NULL) {
t = BuildUNKNOWN(newname(), false, true);
update(&curenv, *n, t);
}
return t; /* no loc. ty. vars, t* or t^e */
} /* typename */
Local typcrec *typeld(ld, btns, splitlevel)
def ld;
envrec *btns;
long splitlevel;
{
/* if ld (appearing in where) is of the form "ns=e" or appset
then check its type; result type is APS
splitlevel: same function as in typeval */
typcrec *t1;
if (ld->tag!=TAGDefCon) /*appsets in where not (yet) in d.s. */
return (BuildAPS());
t1 = BuildUNKNOWN(newname(), false, true);
compat(t1, typeval(false, ld->DefCon.defcon, btns, splitlevel),
ld->DefCon.defcon);
compat(t1, typeval(false, ld->DefCon.conas, btns, splitlevel),
ld->DefCon.conas);
return (BuildAPS());
} /* typeld */
Local Void splitcurenv(splitlevel, ce, le)
long splitlevel;
envrec **ce, **le;
{
/* curenv contains:
conn. names;mark;ADMnames_n;mark;conn. names_n;mark;... ;
ADMnames_0;mark;connnames_0;mark;explicitly declared names
ce will contain:
conn. names;conn. names_n;mark;...; ADMnames_0; mark;
connnames_0; mark;explicitly declared names
le will contain:
ADMnames_n;mark; ... ; ADMnames_0;explicitly declared names
n = splitlevel
*/
envrec *h, *h2, *hold;
long i;
hold = NULL;
h = curenv;
while (!ismark(h)) {
hold = h;
h = h->next;
}
h = h->next;
*le = h;
while (!ismark(h))
h = h->next;
if (hold == NULL)
*ce = h->next;
else {
*ce = curenv;
hold->next = h->next;
}
hold = h;
h = h->next;
for (i = 1; i <= splitlevel; i++) {
while (!ismark(h))
h = h->next;
h = h->next;
while (!ismark(h)) {
h2 = (envrec *)malloc(sizeof(envrec));
*h2 = *h;
hold->next = h2;
hold = h2;
h = h->next;
}
}
while (!ismark(h))
h = h->next;
hold->next = h->next;
} /* splitcurenv */
Local Void atleast(vi, ty, vl)
long vi;
typcrec *ty;
val vl;
{ /* see that ty has at least vi subparts;
vl: where this is checked */
typcrec *t, *t1;
if (vi <= 0)
return;
while (ty->kind == kindINDIR) ty = ty->INDIR.tcind;
switch (ty->kind) {
case kindCT:
atleast(vi - 1, ty->CT.tcrest, vl);
break;
case kindSOME:
t1 = ty->SOME.tcpart;
t = BuildSOME(t1, newname());
while (vi > 0) {
t = BuildCT(t1, t);
vi--;
}
becomes(ty, t);
break;
case kindEMPTYT:
error(24L, NULL, NULL, NULL, vl, false);
break;
case kindUNKNOWN:
becomes(ty,BuildSOME(BuildUNKNOWN(newname(), false,
ty->UNKNOWN.mustconn),
newname()));
/* !! hier ook gevaar verkeerde invulling? */
atleast(vi, ty, vl);
break;
case kindSINGLEARROW:
case kindINT:
case kindFLOAT:
case kindBOOL:
case kindSTRING:
case kindSYSTY:
case kindLOC:
case kindBASETY:
case kindALL:
case kindAPS:
/* blank case */
break;
}
} /* atleast */
Local typcrec *selecttypes(ind1, ind2, ty)
long ind1, ind2;
typcrec *ty;
{
/* ty is a type ty_0 CT (.... CT (ty_n-1 CT rest)) (with
possibly INDIRs) if no error occurred.
The result is to be ty_ind1 CT ( ... (ty_ind2 CT EMPTYT)) */
if (ind2 < ind1) return (BuildEMPTYT());
while (ty->kind == kindINDIR) ty = ty->INDIR.tcind;
if (ty->kind != kindCT) return (BuildUNKNOWN(newname(), false, false));
if (ind1 > 0)
return (selecttypes(ind1 - 1, ind2 - 1, ty->CT.tcrest));
else
return (BuildCT(ty->CT.tcfirst, selecttypes(0L, ind2 - 1, ty->CT.tcrest)));
} /* selecttypes */
Local typcrec *typeval(appnon, vl, btns, splitlevel)
boolean appnon;
val vl;
envrec *btns;
long splitlevel;
/* gives type of vl;
appnon is appset type: system application taken as adirectional
btns: typenamings holding in types found in val
splitlevel: nr. of ATOM/DEF/MAC blocks to be split out of
curenv in local definitions */
{ typcrec *ta, *tf, *t1, *t2;
symbol hnm;
envrec *conenv, *locenv;
def hl;
val hv;
switch (vl->tag) {
case TAGVApply:
ta = typeval(false, vl->VApply.apar, btns, splitlevel);
tf = typeval(false, vl->VApply.aval, btns, splitlevel);
if (appnon) {
t1 = BuildUNKNOWN(newname(), false, true);
compat(BuildSYSTY(BuildOd(BuildNON()), t1),
tf, vl->VApply.aval);
compat(t1, ta, vl->VApply.apar);
return BuildAPS();
} else {
t1 = BuildUNKNOWN(newname(), false, true);
t2 = BuildUNKNOWN(newname(), false, true);
compat(BuildSYSTY(BuildCd(BuildOd(BuildIN()),
BuildCd(BuildOd(BuildOUT()),
BuildOd(BuildNON()))),
BuildCT(t1, BuildCT(t2, BuildEMPTYT()))), tf,
vl->VApply.aval);
compat(t1, ta, vl->VApply.apar);
return t2;
}
break;
case TAGVSym:
hnm = vl->VSym.sym;
return typename(&hnm);
break;
case TAGVLambda:
mark_(&curenv);
mark_(&curenv);
/* simulate empty block of ATOM/DEF/MAC decls. */
splitcurenv(splitlevel, &conenv, &locenv);
curenv = locenv;
t1 = BuildSYSTY(BuildCd(BuildOd(BuildIN()),
BuildCd(BuildOd(BuildOUT()), BuildOd(BuildNON()))),
BuildCT(typefc(vl->VLambda.lpar),
BuildCT(typeval(false, vl->VLambda.lval, btns, 0L),
BuildEMPTYT())));
release_(&curenv, false);
/* the local connames of this lambda abstr. */
curenv = conenv;
return t1;
break;
case TAGVSigma:
mark_(&curenv);
mark_(&curenv);
/* simulate empty block of ATOM/DEF/MAC decls. */
splitcurenv(splitlevel, &conenv, &locenv);
curenv = locenv;
compat(BuildAPS(), typeval(true, vl->VSigma.sval, btns, 0L),
vl->VSigma.sval);
t1 = BuildSYSTY(BuildOd(BuildNON()),
typefc(vl->VSigma.spar));
release_(&curenv, false);
/* the local connames of this sigma abstr. */
curenv = conenv;
return t1;
break;
case TAGVWhere:
mark_(&curenv); /* after formcons and conn. names */
mark_(&btns);
btns = extendbtns(vl->VWhere.wdefs, btns);
extendenvloc(vl->VWhere.wdefs, btns);
mark_(&curenv); /* after ATOM/DEF/Mac names */
hl = vl->VWhere.wdefs;
while (hl != NULL) {
compat(BuildAPS(), typeld(hl, btns, splitlevel + 1), NULL);
/* compat always correct, so nil does not matter */
hl = hl->next;
}
t1 = typeval(appnon, vl->VWhere.wval, btns,splitlevel+1);
splitcurenv(splitlevel, &conenv, &locenv);
curenv = locenv;
checkdms(vl->VWhere.wdefs, btns);
release_(&btns, false);
release_(&curenv, false); /* local ATOM/DEF/MACs removed */
curenv = conenv;
return t1;
break;
case TAGVList:
if (vl->VList.l == NULL)
return BuildEMPTYT();
else {
return
BuildCT(typeval(false,vl->VList.l,btns,splitlevel),
typeval(false, new_VList(vl->VList.l->next), btns,
splitlevel));
}
break;
case TAGVAppset:
t1 = BuildAPS();
hv = vl->VAppset.aps;
while (hv != NULL) {
compat(t1, typeval(true, hv, btns, splitlevel), hv);
hv = hv->next;
}
return t1;
break;
case TAGVAtom:
hnm = vl->VAtom.atnm;
tf = lookup(curenv, &hnm);
if (tf != NULL) {
while (tf->kind == kindSINGLEARROW || tf->kind == kindINDIR) {
if (tf->kind == kindSINGLEARROW)
tf = tf->SINGLEARROW.tcres;
else
tf = tf->INDIR.tcind;
}
ta = typeval(false, vl->VAtom.atcpar, btns, splitlevel);
if (appnon) {
t1 = BuildUNKNOWN(newname(), false, true);
compat(BuildSYSTY(BuildOd(BuildNON()), t1), tf, vl);
compat(t1, ta, vl->VAtom.atcpar);
return BuildAPS();
} else {
t1 = BuildUNKNOWN(newname(), false, true);
t2 = BuildUNKNOWN(newname(), false, true);
compat(BuildSYSTY(BuildCd(BuildOd(BuildIN()),
BuildCd(BuildOd(BuildOUT()),
BuildOd(BuildNON()))),
BuildCT(t1, BuildCT(t2,BuildEMPTYT()))),tf,vl);
compat(t1, ta, vl->VAtom.atcpar);
return t2;
}
} else
error(26L, NULL, NULL, hnm, NULL, false);
return BuildUNKNOWN(newname(),false,false);
break;
case TAGVSyn:
t1 = BuildUNKNOWN(newname(), false, true);
hv = vl->VSyn.synlist;
while (hv != NULL) {
compat(t1, typeval(false, hv, btns, splitlevel), hv);
hv = hv->next;
}
return BuildAPS();
break;
case TAGVComp:
t1 = typeval(false, vl->VComp.vrest, btns, splitlevel);
vl->VComp.typvc = t1;
return BuildCT(typeval(false,vl->VComp.vfirst,btns,
splitlevel),
t1);
break;
case TAGVInd:
if (vl->VInd.vind < 0) {
error(25L, NULL, NULL, NULL, vl, false);
return BuildUNKNOWN(newname(), false, false);
} else {
t1 = typeval(appnon, vl->VInd.vexp, btns, splitlevel);
atleast(vl->VInd.vind + 1, t1, vl);
vl->VInd.typvi = t1;
t2 = selecttypes(vl->VInd.vind, vl->VInd.vind, t1);
if (t2->kind == kindCT)
return t2->CT.tcfirst;
else
return BuildUNKNOWN(newname(), false, false);
}
break;
case TAGVSlice:
if (vl->VSlice.vind2 < vl->VSlice.vind1)
return BuildEMPTYT();
else {
if (vl->VSlice.vind1 < 0) {
error(25L, NULL, NULL, NULL, vl, false);
return BuildUNKNOWN(newname(), false, false);
} else {
t1 = typeval(appnon, vl->VSlice.vexps, btns, splitlevel);
atleast(vl->VSlice.vind2 + 1, t1, vl);
vl->VSlice.typvs = t1;
return selecttypes(vl->VSlice.vind1, vl->VSlice.vind2,
t1);
}
}
break;
}/* case */
} /* typeval */
Void checksize(glass)
def_list glass;
{ /* check if size of connections ok; if errors found, deliver
errors, otherwise changed data structure */
envrec *btns;
def hdef, nw;
_PROCEDURE TEMP;
errordiscovered = false;
forfull = false;
marker = Buildsymbol("",0L); /* initialisation of a constant */
namessupply = 0;
nestednames = NULL;
nestednorig = NULL;
btns = emptyenv;
mark_(&btns);
btns = extendbtns(glass, btns);
curenv = emptyenv;
mark_(&curenv);
extendenvloc(glass, btns);
checkdms(glass, btns);
release_(&btns, false);
release_(&curenv, false);
hdef = glass;
if (errorlist == NULL) {
while (hdef != NULL) {
if (hdef->tag == TAGDefVal)
replconsind(hdef->DefVal.valas, false, &nw);
hdef = hdef->next;
}
}
TEMP.proc = (Anyptr)unparsval;
TEMP.link = (Anyptr)NULL;
printerrors(TEMP, errorlist);
} /* checksize */